package com.czl.app.controller;

import com.czl.app.config.ResultJson;
import com.czl.app.model.UserInfo;
import com.czl.app.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/user")
@Api(tags = "用户管理" +
        "")
public class LoginController {

    @Resource
    private UserService userService;

    @PostMapping("/login")
    @ApiOperation("用户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "string", required = true),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "string", required = true)
    })
    public ResultJson login(String userName, String password) {
        try {
            UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            String sessionId = subject.getSession().getId().toString();
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("token", sessionId);
            return new ResultJson("200", "登录成功！", hashMap);
        } catch (UnknownAccountException e) {
            //账号不存在
            return new ResultJson("400", "用户名或者密码错误！", null);
        } catch (DisabledAccountException e) {
            return new ResultJson("400", "该账户被禁用！", null);
        } catch (IncorrectCredentialsException e) {
            return new ResultJson("400", "用户名或者密码错误！", null);
        } catch (Exception e) {
            return new ResultJson("400", "未知错误，请联系管理员！", null);
        }
    }

    @GetMapping("/need_login")
    public ResultJson needLogin() {
        return new ResultJson("400", "请先登录！", "null");
    }

    @GetMapping("/unauth")
    public ResultJson unauth() {
        return new ResultJson("400", "您不具备相应权限", "null");
    }

    @PostMapping("/add_user")
    @ApiOperation("添加用户")
    //@RequiresAuthentication
    @RequiresRoles(value = {"admin", "czl"}, logical = Logical.OR)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "鉴权Token", dataType = "String", required = true, paramType = "header"),
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", required = true),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", required = true),
            @ApiImplicitParam(name = "roleName", value = "角色名", dataType = "String", required = true)
    })
    public ResultJson addUser(String userName, String password, String roleName) {
        try {
            userService.addUser(userName, password, roleName);
            return new ResultJson("200", "添加用户成功!", null);
        } catch (Exception e) {
            return new ResultJson("400", "添加用户失败!", null);
        }
    }

    @PostMapping("/del_user")
    @ApiOperation("删除用户")
    @RequiresRoles(value = {"admin", "czl"}, logical = Logical.OR)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "鉴权Token", dataType = "String", required = true, paramType = "header"),
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", required = true),
    })
    public ResultJson DelUser(String userName) {
        try {
            userService.delUser(userName);
            return new ResultJson("200", "删除用户成功!", null);
        } catch (Exception e) {
            return new ResultJson("400", "删除用户失败!", null);
        }
    }

    @PostMapping("/reset_password")
    @ApiOperation("重置用户密码")
    @RequiresRoles(value = {"admin", "czl"}, logical = Logical.OR)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "鉴权Token", dataType = "String", required = true, paramType = "header"),
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", required = true),
    })
    public ResultJson resetPassword(String userName) {
        try {
            userService.adminUpadate(userName);
            return new ResultJson("200", "重置用户密码成功!初始密码为：123123", null);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultJson("400", "重置用户密码失败!", null);
        }
    }

    @PostMapping("/reset_self_password")
    @ApiOperation("重置自己的密码")
    //只要登录验证通过就可以使用这个方法
    @RequiresAuthentication
    @ApiImplicitParams({
            @ApiImplicitParam(name = "oldPwd", value = "旧密码", dataType = "String", required = true),
            @ApiImplicitParam(name = "password", value = "新密码", dataType = "String", required = true)
    })
    public ResultJson resetSetPassword(String oldPwd, String password) {
        Subject subject = SecurityUtils.getSubject();
        UserInfo userInfo = (UserInfo) subject.getPrincipals().getPrimaryPrincipal();
        try {
            if (!userService.verifyPassword(userInfo.getPassword(), userInfo.getSalt(), oldPwd)) {
                return new ResultJson("200", "旧密码不正确!", null);
            } else {
                userService.selfUpadate(userInfo.getUserName(), password);
                return new ResultJson("200", "重置用户密码成功!", null);
            }
        } catch (Exception e) {
            return new ResultJson("400", "重置用户密码失败!", null);
        }
    }

    @PostMapping("/upd_disableAccount")
    @ApiOperation("禁止用户登录")
    //@RequiresAuthentication
    @RequiresRoles(value = {"admin"}, logical = Logical.OR)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "鉴权Token", dataType = "String", required = true, paramType = "header"),
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", required = true)
    })
    public ResultJson disableAccount(String userName) {
        try {
            userService.updDisableAccount(userName);
            return new ResultJson("200", "禁止用户登录成功!", null);
        } catch (Exception e) {
            return new ResultJson("400", "禁止用户登录失败!", null);
        }
    }

    @PostMapping("/upd_enableAccount")
    @ApiOperation("允许用户登录")
    //@RequiresAuthentication
    @RequiresRoles(value = {"admin"}, logical = Logical.OR)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "鉴权Token", dataType = "String", required = true, paramType = "header"),
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", required = true)
    })
    public ResultJson enableAccount(String userName) {
        try {
            userService.updEnableAccount(userName);
            return new ResultJson("200", "允许用户登录成功!", null);
        } catch (Exception e) {
            return new ResultJson("400", "允许用户登录失败!", null);
        }
    }

    @PostMapping("/upd_resetRoles")
    @ApiOperation("修改用户拥有的角色")
    //@RequiresAuthentication
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "鉴权Token", dataType = "String", required = true, paramType = "header"),
            @ApiImplicitParam(name = "userName", value = "用户名", dataType = "String", required = true),
            @ApiImplicitParam(name = "userName", value = "角色名", dataType = "String", required = true)
    })
    public ResultJson resetRoles(String userName, String roleName) {
        try {
            userService.updResetRoles(userName, roleName);
            return new ResultJson("200", "修改用户角色成功!", null);
        } catch (Exception e) {
            return new ResultJson("400", "修改用户角色失败!", null);
        }
    }

    @PostMapping("/find_SelfUserInfo")
    @ApiOperation("查询本用户信息")
    @RequiresAuthentication
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "鉴权Token", dataType = "String", required = true, paramType = "header")
    })
    public ResultJson findSelfUserInfo() {
        try {
            Subject subject = SecurityUtils.getSubject();
            UserInfo userInfo = (UserInfo) subject.getPrincipals().getPrimaryPrincipal();
            UserInfo userInfo1 = userService.findUserInfo(userInfo.getUserName());
            return new ResultJson("200", "查询用户信息成功!", userInfo1);
        } catch (Exception e) {
            return new ResultJson("400", "查询用户信息失败!", null);
        }
    }

    @PostMapping("/find_AllUserInfo")
    @ApiOperation("查询所有用户信息")
    @RequiresRoles(value = {"admin"}, logical = Logical.OR)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "鉴权Token", dataType = "String", required = true, paramType = "header")
    })
    public ResultJson findAllUserInfo() {
        try {
            List<UserInfo> userInfoAll = userService.findUserInfoAll();
            return new ResultJson("200", "查询所有用户信息成功!", userInfoAll);
        } catch (Exception e) {
            return new ResultJson("400", "查询所有用户信息失败!", null);
        }
    }

    @PostMapping("/error")
    @ApiOperation("错误页面")
    @RequiresAuthentication
    @ExceptionHandler(value={org.apache.shiro.authz.AuthorizationException.class})
    public ResultJson authorizationExceptionHandler(Exception e){
        return new ResultJson("400", "你所拥有的权限不足!", e.toString());
    }
}
